#include "qe_log.h"
#include "qe_shell.h"
#include "qe_string.h"
#include "qe_argparse.h"
#if (CONFIG_CMD_LOG_SEND)
#include "fymodem.h"
#endif


static qe_const_str usages[] = {
    "log [options] [[--] args]",
    "log [options]",
    QE_NULL,
};

static qe_ret action_show_domains(qe_argparse *parser, qe_option *option)
{
    qelog_domain_show();
    return qe_yield;
}

static void cmd_logd(int argc, const char *argv[])
{
    qe_ret ret;
    qe_str name = QE_NULL;
    qe_int level = QELOG_WARNING;
    qe_argparse parser;

    qe_option options[] = {
        QE_OPT_ACTION('s', "show", "show log domains",
            QE_NULL, action_show_domains),
        QE_OPT_STRING('n', "name", "domain name", &name),
        QE_OPT_INTEGER('l', "level", "domain level", &level),
        QE_OPT_HELP('h', "help", "domain help"),
        QE_OPT_END(),
    };

    qe_argp_init(&parser, options, usages,
        "\nlog domain command.",
        "\nlog domain command end.");

    ret = qe_argp_parse(&parser, argc, argv);
    if (ret != qe_ok) {
        return;
    }

    if (!level)
        return;

    qelog_domain_set_level(name, level);

    qe_printf("set domain:%s level:%d"QE_ENDLINE, name, level);
}
QE_SHELL_EXPORT_CMD_EXEC(logd, cmd_logd, logb commands);

QE_SHELLCMD_FORCE_EXPORT(logd);

static qe_ret action_buf_clear(qe_argparse *parser, qe_option *option)
{
    qe_ringbuffer *rb = (qe_ringbuffer *)qe_option_data(option);
    qe_ringbuffer_clear(rb);
    return qe_yield;
}

#if (CONFIG_CMD_LOG_SEND)
static qe_ret action_buf_send(qe_argparse *parser, qe_option *option)
{
    qe_int n;
    int length;
    qe_ringbuffer *rb = (qe_ringbuffer *)qe_option_data(option);
    length = qe_ringbuffer_wait(rb);
    n = fymodem_send((qe_u8 *)rb->buf, length, "log");
    qe_printf("send log %dbytes\r\n", n);
    return qe_yield;
}
#endif

static void cmd_logb(int argc, const char *argv[])
{
    qe_ret ret;
    qe_int length = -1;
    qe_str name = QE_NULL;
    qe_ringbuffer *rb;
    qe_argparse parser;

    rb = qelog_get_buffer();
    if (!rb) {
        qe_printf("log buffer null\r\n");
        return;
    }

    qe_option options[] = {
        QE_OPT_INTEGER('l', "len", "display len (-1:all)", &length),
        QE_OPT_ACTION('c', "clear", "clear buf",
            rb, action_buf_clear),
#if (CONFIG_CMD_LOG_SEND)
        QE_OPT_ACTION('s', "send", "ymodem send log buffer",
            rb, action_buf_send),
#endif
        QE_OPT_HELP('h', "help", "buf help"),
        QE_OPT_END(),
    };

    qe_argp_init(&parser, options, usages,
        "\nlog buf command.",
        "\nlog buf command end.");

    ret = qe_argp_parse(&parser, argc, argv);
    if (ret != qe_ok) {
        return;
    }

    if (length < 0)
        length = qe_ringbuffer_wait(rb);

    if (!length) {
        qe_printf("buf is empty\r\n");
        return;
    }

    qe_printf("%.*s", length, rb->buf);
}
QE_SHELL_EXPORT_CMD_EXEC(logb, cmd_logb, logb commands);

QE_SHELLCMD_FORCE_EXPORT(logb);
static qe_ret action_set_output(qe_argparse *parser, qe_option *option)
{
    qe_int val = qe_option_integer(option);
    qe_bool en = val == 1 ? qe_true : qe_false;
    qelog_set_output_enable(en);
    qe_printf("set log output en %d\r\n", en);
    return qe_yield;
}

static void cmd_log(int argc, char *argv[])
{
    qe_ret ret;
    qe_int en = 0;
    qe_argparse parser;

    qe_option options[] = {

        QE_OPT_ACTION('d', "show-domains", "show log domains",
            QE_NULL, action_show_domains),

        QE_ACT_INTEGER('o', "output-en", "set output enable",
            &en, QE_NULL, action_set_output),

        QE_OPT_HELP('h', "help", "help message"),
        QE_OPT_END(),
    };

    qe_argp_init(&parser, options, usages,
    		"\nlog command.",
			"\nlog command.");
    
    ret = qe_argp_parse(&parser, argc, (qe_const_str *)argv);
    if (ret != qe_ok)
        return;

    qelog_show_summary();
}
QE_SHELL_EXPORT_CMD_EXEC(log, cmd_log, log commands);

QE_SHELLCMD_FORCE_EXPORT(log);